Skip to main content

Data Type: REFERENCE TO

Important

With compiler version >= V3.3.0.0, references are initialized (at 0).

Important

If a reference refers to a device input, then the access is applied as write access. When the code is generated, this leads to the compiler warning: "...invalid assignment target".

Example: rInput REF= Input;

If you require a construct of this kind, you need to first copy the input value (example: rInput) to a variable with write access.

A reference with the REFERENCE data type implicitly refers to another object. The assignment is done with the REF= operator. When accessed, the reference is implicitly dereferenced, and therefore does not need a special content operator ^ such as a pointer.

Syntax

<identifier> : REFERENCE TO <data type> ;
<data type>: base type of the reference
Example 214. Valid declaration
PROGRAM PLC_PRG
VAR
    rspeA : REFERENCE TO DUT_SPECIAL;
    pspeA : POINTER TO DUT_SPECIAL;
    speB : DUT_SPECIAL;
END_VAR
rspeA REF= speB; // Reference rspeA is alias for speB. The code corresponds to pspeA := ADR(speB);
rspeA := speD; // The code corresponds to pspeA^ := speD;


Example 215. Invalid declarations
ariTest : ARRAY[0..9] OF REFERENCE TO INT;
priTest : POINTER TO REFERENCE TO INT;
rriTest : REFERENCE TO REFERENCE TO INT;
rbitTest : REFERENCE TO BIT;


A reference type must not be used as the base type of an array, pointer, or reference. Furthermore, a reference must not refer to a bit variable. These kinds of constructs generate compiler errors.

Note

The readability of a program is made difficult when the same memory cell is accessed simultaneously by means of an identifier and its alias.

Example: speB and rspeA

Tip

References and pointers to BIT variables are invalid declarations, as well as array elements with base type BIT.

Example 216. Examples

When references are assigned with :=, a value is always copied, no matter whether the reference is on the left, on the right, or on both sides:

  • Ref := value writes the value value to the location where the reference points to. In pointer notation: Ref^ := value

  • value := Ref writes the value which the reference points to after value. In pointer notation: value := Ref^

  • Ref1 := Ref2 writes the value which Ref2 points to. at the location where Ref1 points to. In pointer notation: Ref1^ := Ref2^

When REF= is used, the address is always applied and there has to be a reference on the left side:

  • Ref REF= value: The reference points to value. In pointer notation: Ref :=ADR(value)

  • Ref1 REF= Ref2: Ref1 points to the same value as Ref2. In pointer notation: Ref1 := Ref2

  • Value REF = Ref leads to a compile error



Tip

In the declaration, REFERENCE TO INT REF= value behaves like REFERENCE TO INT := value.

Comparison of reference and pointer

. A reference has the following advantages over a pointer:
  • Easier to use:

    A reference can access the contents of the referenced object directly and without dereferencing.

  • Finer and simpler syntax when passing values:

    Call of a function block which passes a reference without an address operator instead of a pointer

    Example: fbDoIt(riInput:=iValue);

    Instead of: fbDoIt_1(piInput:=ADR(iValue));

  • Type safety:

    When assigning two references, the compiler checks whether their base types match. This is not checked in the case of pointers.

Testing the validity of a reference

You can use the operator __ISVALIDREF to check whether or not a reference points to a valid value (meaning a value not equal to 0).

Syntax

<boolean variable name> := __ISVALIDREF( <reference name> );

<reference name>: Identifier declared with REFERENCE TO

The Boolean variable is TRUE when the reference points to a valid value. Otherwise it is FALSE.

PROGRAM PLC_PRG
VAR
    iAlfa : INT;
    riBravo : REFERENCE TO INT;
    riCharlie : REFERENCE TO INT;
    bIsRef_Bravo : BOOL := FALSE;
    bIsRef_Charlie : BOOL := FALSE;
END_VAR
iAlfa := iAlfa + 1;
riBravo REF= iAlfa;
riCharlie REF= 0;
bIsRef_Bravo := __ISVALIDREF(riBravo);  (* becomes TRUE, because riBravo references to iAlfa, which is non-zero *)
bIsRef_Charlie := __ISVALIDREF(riCharlie); (* becomes FALSE, because riCharlie is set to 0 *)

Tip

In compiler version 3.5.7.40 and higher, the implicit monitoring function CheckPointer acts on variables of type REFERENCE TO in the same way as for pointer variables.